#include "slog2.h"
#include "common.h"
#include <sys/slog2.h>
#include <iostream>
#include <string>

static std::string application_id_;
static std::string description_;
static Slog2VerbosityLevel verbosity_;
static slog2_buffer_set_config_t config_;
static slog2_buffer_t handle_;


static uint8_t toVerbosity(Slog2VerbosityLevel verbosity_level)
{
    uint8_t verbosity = SLOG2_SHUTDOWN;
    switch (verbosity_level)
    {
        case Slog2VerbosityLevel::kShutdown:
            verbosity = SLOG2_SHUTDOWN;
            break;
        case Slog2VerbosityLevel::kCritical:
            verbosity = SLOG2_CRITICAL;
            break;
        case Slog2VerbosityLevel::kError:
            verbosity = SLOG2_ERROR;
            break;
        case Slog2VerbosityLevel::kWarning:
            verbosity = SLOG2_WARNING;
            break;
        case Slog2VerbosityLevel::kNotice:
            verbosity = SLOG2_NOTICE;
            break;
        case Slog2VerbosityLevel::kInfo:
            verbosity = SLOG2_INFO;
            break;
        case Slog2VerbosityLevel::kDebug1:
            verbosity = SLOG2_DEBUG1;
            break;
        case Slog2VerbosityLevel::kDebug2:
            verbosity = SLOG2_DEBUG2;
            break;
        default:
            verbosity = SLOG2_SHUTDOWN;
            break;
    }

    return verbosity;
}

Slog2ReturnValue Slog2RegisterApplication(
		const std::string application_id,
                const std::string description,
		Slog2VerbosityLevel verbosity_level)
{
    application_id_ = application_id;
    description_ = description;
    verbosity_ = verbosity_level;

    config_.buffer_set_name = application_id_.c_str();
    config_.num_buffers = 1;
    config_.verbosity_level = toVerbosity(verbosity_level);
    config_.buffer_config[0].buffer_name = "default_logging";
    config_.buffer_config[0].num_pages = 40;

    int ret = slog2_register(&config_, &handle_, SLOG2_ALLOC_TYPE_SHMEM | SLOG2_DISCARD_NEWLINE);
    if (0 != ret) {
        std::cerr << "slog2_register fail, ret:" << ret << ", errno:" << errno << std::endl;
        return Slog2ReturnValue::kReturnError;
    }

    // set default buffer for logging
    (void)slog2_set_default_buffer(handle_);

    return Slog2ReturnValue::kReturnOk;
}

Slog2ReturnValue Slog2UnregisterApplication()
{
    int ret = slog2_reset();
    if (0 != ret) {
        std::cerr << "slog2_reset fail, ret:" << ret << ", errno:" << errno << std::endl;
        return Slog2ReturnValue::kReturnError;
    }

    return Slog2ReturnValue::kReturnOk;
}
